package com.diors.game.engine.thread;

import java.util.concurrent.ScheduledFuture;
import java.util.concurrent.ScheduledThreadPoolExecutor;
import java.util.concurrent.TimeUnit;

import org.apache.log4j.Logger;

import com.diors.commons.thread.CommonsExecutionHandler;
import com.diors.commons.thread.PriorityThreadFactory;
import com.diors.commons.thread.SelecterThreadPoolExecutor;
import com.diors.commons.thread.task.Action;
import com.diors.commons.thread.task.SelecterAction;

/**
 * 线城池管理类
 * @author darren.ouyang
 * @date 2013-9-15
 */
public class ThreadPoolManager 
{
	static Logger log = Logger.getLogger(ThreadPoolManager.class);
	
	private static final class SingletonHolder
	{
		private static final ThreadPoolManager	INSTANCE	= new ThreadPoolManager();
	}

	public static ThreadPoolManager getInstance()
	{
		return SingletonHolder.INSTANCE;
	}
	
	/**
	 * 最大延迟时间
	 */
	private final static long MAX_DELAY = TimeUnit.NANOSECONDS.toMillis(Long.MAX_VALUE - System.nanoTime()) / 2;
	
	/**
	 * 执行网络解包任务池
	 */
	private final SelecterThreadPoolExecutor networkPool;
	
	/**
	 * 执行游戏业务的定时任务
	 */
	private final ScheduledThreadPoolExecutor scheduledPool;
	
	/**
	 * 执行游戏业务的延迟任务
	 */
	private final ScheduledThreadPoolExecutor actionPool;
	
	/**
	 * 执行关闭连接触发的任务
	 */
	//private final ScheduledThreadPoolExecutor disconnectionPool;
	
	/**
	 * 执行AI线程池
	 */
	//private final ScheduledThreadPoolExecutor actionPool;
	
	
	/**
	 * 执行任务的线程池
	 */
	//private final ThreadPoolExecutor instantPool;
	
	
	/**
	 * 长时间线程池
	 */
	//private final ThreadPoolExecutor longinstantPoll;
	
	private ThreadPoolManager()
	{
		final int instantPoolSize = 2 ;//Math.max(1, ThreadConfig.THREAD_POOL_SIZE / 3);
		
		
		
		networkPool = new SelecterThreadPoolExecutor(new PriorityThreadFactory("network Pool", Thread.NORM_PRIORITY));
		
		scheduledPool = new ScheduledThreadPoolExecutor(instantPoolSize, new PriorityThreadFactory("ScheduledPool", Thread.NORM_PRIORITY));
		scheduledPool.setRejectedExecutionHandler(new CommonsExecutionHandler());
		scheduledPool.prestartAllCoreThreads();
		
		actionPool = new ScheduledThreadPoolExecutor(instantPoolSize, new PriorityThreadFactory("ActionPool", Thread.NORM_PRIORITY));
		actionPool.setRejectedExecutionHandler(new CommonsExecutionHandler());
		actionPool.prestartAllCoreThreads();
		
		/*actionPool = new ScheduledThreadPoolExecutor(instantPoolSize, new PriorityThreadFactory("ActionPool", Thread.NORM_PRIORITY));
		actionPool.setRejectedExecutionHandler(new CommonsExecutionHandler());
		actionPool.prestartAllCoreThreads();
		
		instantPool = new ThreadPoolExecutor(instantPoolSize, instantPoolSize, 6L, TimeUnit.SECONDS, new ArrayBlockingQueue<Runnable>(100000), new PriorityThreadFactory("instance Pool", Thread.NORM_PRIORITY));
		instantPool.setRejectedExecutionHandler(new CommonsExecutionHandler());
		instantPool.prestartAllCoreThreads();
		
		longinstantPoll = new ThreadPoolExecutor(0, Integer.MAX_VALUE, 6L, TimeUnit.SECONDS, new SynchronousQueue<Runnable>(), new PriorityThreadFactory("LongInstant Pool", Thread.NORM_PRIORITY));
		longinstantPoll.setRejectedExecutionHandler(new CommonsExecutionHandler());
	
		
		disconnectionPool = new ScheduledThreadPoolExecutor(4, new PriorityThreadFactory("DisconnectionPool", Thread.NORM_PRIORITY));
		disconnectionPool.prestartAllCoreThreads();
		//disconnectionPool.setRemoveOnCancelPolicy(true);*/
	}
	
	
	/**
	 * 执行一个选择器任务(selecterCode返回值相同的任务必定在同一线程内执行)
	 * @param task	选择器任务
	 * @create	2013-10-22	darren.ouyang
	 */
	public final void executeSelecter(int source, SelecterAction task)
	{
		networkPool.execute(task);
	}
	
	
	
	
	/**
	 * 立即执行一个任务
	 * @param source	来源
	 * @param action	任务
	 * @create	2013-10-22	darren.ouyang
	 */
	public final void execute(int source, Action action)
	{
		scheduledPool.execute(action);
	}

	/**
	 * 创建并执行在给定延迟后启用的一次性操作。
	 * @param source	来源
	 * @param action	任务
	 * @param delay		延迟的时间
	 * @return			结果
	 * @create	2013-10-22	darren.ouyang
	 */
	public final ScheduledFuture<?> schedule(int source, Action action, long delay)
	{
		validate(delay);
		
		return scheduledPool.schedule(action, delay, TimeUnit.MILLISECONDS);
	}
	
	
	
	/**
	 *  创建并执行一个在给定初始延迟后首次启用的定期操作，后续操作具有给定的周期；
	 *  也就是将在 initialDelay 后开始执行，然后在 initialDelay+period 后执行，
	 *  接着在 initialDelay + 2 * period 后执行，依此类推。
	 * @param source	来源
	 * @param action	执行的任务
	 * @param delay		首次执行的延迟时间
	 * @param period	连续执行之间的周期
	 * @return			任务结果
	 * @create	2013-10-22	darren.ouyang
	 */
	public final ScheduledFuture<?> scheduleAtFixedRate(int source, Action action, long delay, long period)
	{
		delay = validate(delay);
		period = validate(period);

		return scheduledPool.scheduleAtFixedRate(action, delay, period, TimeUnit.MILLISECONDS);
	}
	
	/**
	 * 创建并执行一个在给定初始延迟后首次启用的定期操作，
	 * 随后，在每一次执行终止和下一次执行开始之间都存在给定的延迟。
	 * @param source		来源
	 * @param action		需要执行的任务
	 * @param initialDelay	首次执行的延迟时间
	 * @param delay			一次执行终止和下一次执行开始之间的延迟
	 * @return				任务结果
	 * @create	2013-10-22	darren.ouyang
	 */
	public final ScheduledFuture<?> scheduleWithFixedDelay(int source, Action action, long initialDelay, long delay)
	{
		initialDelay = validate(initialDelay);
		delay = validate(delay);
		return scheduledPool.scheduleWithFixedDelay(action, initialDelay, delay, TimeUnit.MILLISECONDS);
	}
	
	/**
	 * 验证时间是否正确
	 * @param delay			时间
	 * @return				返回验证后的时间
	 * @create	2013-10-22	darren.ouyang
	 */
	private final long validate(long delay)
	{
		return Math.max(0, Math.min(MAX_DELAY, delay));
	}
}
